package com.isoft.uaaservice.service.impl;



import com.isoft.uaaservice.bean.LoginSysUserDetails;
import com.isoft.uaaservice.bean.ResponseData;
import com.isoft.uaaservice.bean.ResultCode;
import com.isoft.uaaservice.bean.SysUser;
import com.isoft.uaaservice.dao.SysUserDao;
import com.isoft.uaaservice.service.ISysLoginService;
import com.isoft.uaaservice.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@Transactional
public class SysLoginServiceImpl implements ISysLoginService {
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    SysUserDao sysUserDao;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    RedisUtil redisUtil;
    /*登录*/
    @Override
    public ResponseData login(SysUser sysUser) {
        //输入信息校验
        ResponseData responseData =new ResponseData();
        if (null == sysUser || sysUser.getUsername() == null || sysUser.getUsername().trim().length() == 0){
            log.error("登录用户信息不完整");
            responseData.setErrorCode(ResultCode.PARAM_NOT_VALID.getCode());
            responseData.setMsg(ResultCode.PARAM_NOT_VALID.getMessage());
            return responseData;
        }
        log.info(sysUser.toString());
        //发起认证
        System.out.println("-----------------------------------------------------------SysLoginServiceImpl-1");
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getUsername() , sysUser.getPassword());
        System.out.println("-----------------------------------------------------------SysLoginServiceImpl-2");
        Authentication authentication = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        System.out.println("-----------------------------------------------------------SysLoginServiceImpl-3");
        if(null == authentication){//认证失败
            log.error("认证失败");
            throw new RuntimeException("认证失败！");
        }else{//认证成功
            log.info(authentication.toString());
            //获取登录用户信息
            LoginSysUserDetails loginSysUserDetails = (LoginSysUserDetails) authentication.getPrincipal();
            Integer id = loginSysUserDetails.getSysUser().getId();
            log.info("获取登录用户信息成功");
            //生成jwt(token)
            String jwt = JwtUtil.createJWT(String.valueOf(id));
            log.info("生成jwt(token)成功");
            //存入redis
            redisUtil.setCacheObject(RedisKeyUtil.keyLoginSysuser(id) , loginSysUserDetails);
            log.info("存入redis成功");


            //构造返回Controller 的结果
            responseData.setErrorCode(ResultCode.SUCCESS.getCode());
            responseData.setMsg(ResultCode.SUCCESS.getMessage());
            log.info("认证成功");
            Map<String , Object> map = new HashMap<>();
            map.put("token",jwt);
            map.put("sysuser", loginSysUserDetails.getSysUser());
            map.put("permission" , ((LoginSysUserDetails) authentication.getPrincipal()).getAllowList());
            responseData.setData(map);
            return responseData;
        }
    }

    /*退出*/
    @Override
    public ResponseData logout() {
            // 获取当前认证信息
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            log.info("logout :" + authentication);
            if (null == authentication){
                throw new RuntimeException("获取authentication异常！");
            }
            LoginSysUserDetails loginSysUser = (LoginSysUserDetails) authentication.getPrincipal();
            if (null == loginSysUser){
                throw new RuntimeException("获取用户信息异常！");
            }
            Integer uid = loginSysUser.getSysUser().getId();
            // 删除 Redis 中相应的数据
            redisUtil.delete(RedisKeyUtil.keyLoginSysuser(uid));
            log.info("删除 Redis 对应用户数据成功");

            // 构造返回 Controller 的结果
            ResponseData responseData = new ResponseData();
            responseData.setErrorCode(ResultCode.SUCCESS.getCode());
            responseData.setMsg(ResultCode.SUCCESS.getMessage());
            responseData.setData(true);
            return responseData;
    }

    /*用户注册（默认外部用户）*/
    @Override
    public boolean register(SysUser sysUser) {
        if (null == sysUser || StringUtil.isEmpty(sysUser.getUsername())){
            return false;
        }

        String pwd = "" ;// 密码为空就初始化为abc123
        try {
            if (StringUtil.isEmpty(sysUser.getPassword())){
                pwd = passwordEncoder.encode("abc123");
            }else {
                pwd = passwordEncoder.encode(sysUser.getPassword());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        sysUser.setPassword(pwd);
        // 创建用户时间为系统时间
        sysUser.setCreatedt(new Date());
        return sysUserDao.register(sysUser)>0;
    }
    /*远程访问提供注册接口（合同工普通员工）*/
    @Override
    public boolean registerRestTemplate(SysUser sysUser) {
        if (null == sysUser || StringUtil.isEmpty(sysUser.getUsername())){
            return false;
        }
        String pwd = "" ;//进行密码加密
        try {
            pwd = passwordEncoder.encode(sysUser.getPassword());
        } catch (Exception e) {
            log.error("密码加密失败");
            e.printStackTrace();
        }
        sysUser.setPassword(pwd);
        // 创建用户时间为系统时间
        sysUser.setCreatedt(new Date());
        return sysUserDao.registerRestTemplate(sysUser)>0;
    }

    /*忘记密码*/
    //1.获取指定用户信息
    @Override
    public SysUser getNewOne(SysUser sysUser) {
        return sysUserDao.getNewOne(sysUser);
    }
    //2.修改密码
    @Override
    public boolean changePassword(SysUser sysUser) {
        if((null == sysUser)||(StringUtil.isEmpty(sysUser.getPassword()))){
            return false;
        }
        //修改后的密码重新加密
        String pwd = "" ;
        try {
            pwd = passwordEncoder.encode(sysUser.getPassword());
        }catch (Exception e){
            e.printStackTrace();
        }
        sysUser.setPassword(pwd);
        return sysUserDao.changePassword(sysUser)>0;
    }

    /*修改用户密码*/
    @Override
    public boolean updatePasswordById(SysUser sysUser) {
        if((null == sysUser)||(!IdUtil.idCheck(sysUser.getId()))||(StringUtil.isEmpty(sysUser.getPassword()))){
            return false;
        }
        //修改后的密码重新加密
        String pwd = "" ;
        try {
            pwd = passwordEncoder.encode(sysUser.getPassword());
        }catch (Exception e){
            e.printStackTrace();
        }
        sysUser.setPassword(pwd);
        return sysUserDao.updatePasswordById(sysUser)>0;
    }

    /*修改用户头像*/
    @Override
    public boolean changeUserPhoto(Integer id,String saveFileUrl) {
        if((!IdUtil.idCheck(id))||(StringUtil.isEmpty(saveFileUrl))){
            return false;
        }
        SysUser sysUser= new SysUser();
        sysUser.setId(id);
        sysUser.setPhotourl(saveFileUrl);
        return sysUserDao.changeUserPhoto(sysUser)>0;
    }

    /*账户冻结与启用*/
    @Override
    public boolean freezeAndEnable(SysUser sysUser) {
        if (sysUser == null){
            return false;
        }
        return sysUserDao.freezeAndEnable(sysUser.getUsername() , sysUser.getIslock())>0;
    }
}
